package com.example.portablefortheelderlybackground.sevice.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.portablefortheelderlybackground.common.key.paramsKey;
import com.example.portablefortheelderlybackground.common.redis.redisKey;
import com.example.portablefortheelderlybackground.mapper.surveyMapper;
import com.example.portablefortheelderlybackground.pojo.question.survey;
import com.example.portablefortheelderlybackground.sevice.questionService;
import com.example.portablefortheelderlybackground.sevice.surveyService;
import com.example.portablefortheelderlybackground.utils.PageUtil.PageGenerateUtil;
import com.example.portablefortheelderlybackground.vo.questionVo.surveyVo;
import com.example.portablefortheelderlybackground.vo.questionVo.topicVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.example.portablefortheelderlybackground.Enum.other.SurveyOther.IS_CURRENTLY;
import static com.example.portablefortheelderlybackground.common.StringCommon.TimeOut;
//todo 添加redis缓存

@Transactional(timeout = 5)
@Slf4j
@Service
public class surveyServiceImpl extends ServiceImpl<surveyMapper, survey> implements surveyService {

    final
    RedisTemplate<String, Object> redisTemplate;
    final
    questionService questionService;

    @Autowired
    public surveyServiceImpl(RedisTemplate<String, Object> redisTemplate, questionService questionService) {
        this.redisTemplate = redisTemplate;
        this.questionService = questionService;
    }

    @Override
    public IPage<surveyVo> getSurveyById(String id) {
        IPage<surveyVo> surveyVoIPage = (IPage<surveyVo>) redisTemplate.opsForValue().get(redisKey.surveyKey + id);
        if (!ObjectUtils.isEmpty(surveyVoIPage)) {
            return surveyVoIPage;
        }
        //先获取survey,拿到type去与question的type进行匹配
        //构建queryWrapper
        LambdaQueryWrapper<survey> queryWrapper = new LambdaQueryWrapper<>();
        //构建属性添加，是否逻辑删除，id相等
        queryWrapper.eq(survey::getIsDelete, paramsKey.NOT_DELETE).eq(survey::getId, id);
        survey survey = baseMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(survey)) {
            //如果为空,则表示不存在,直接返回null
            return null;
        }
        Page<topicVo> topicVoPage = PageGenerateUtil.PageVoGenerate(new topicVo());
        //todo 这里需要修改,这里的大小默认是10
        IPage<topicVo> allTopicVo = questionService.getAllTopicVoById(topicVoPage, id);
        //创建surveyVo对象
        surveyVo surveyVo = new surveyVo();
        //属性拷贝
        BeanUtils.copyProperties(survey, surveyVo, "isDelete", "createTime");
        surveyVo.setTopicVoList(allTopicVo.getRecords());
        Page<surveyVo> surveyVoPage = PageGenerateUtil.PageVoGenerate(surveyVo);
        BeanUtils.copyProperties(allTopicVo, surveyVoPage, "records");
        //设置问题数量
        surveyVo.setCount(allTopicVo.getRecords().size());
        surveyVoPage.setRecords(List.of(surveyVo));
        //存缓存
        redisTemplate.opsForValue().set(redisKey.surveyKey + id, surveyVoPage, TimeOut, TimeUnit.HOURS);
        return surveyVoPage;
    }

    @Override
    public Boolean saveSurveyVoPeoples(surveyVo vo) {
        //对vo进行非空判断，其实不用判断，作参数校验即可
        if (ObjectUtils.isEmpty(vo))
            return false;
        //操作baseMapper,构建queryWrapper,通过vo的id
        LambdaQueryWrapper<survey> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StringUtils.hasLength(vo.getId()), survey::getId, vo.getId());
        //先查询对应survey
        survey survey = baseMapper.selectOne(queryWrapper);
        //对survey进行判断
        if (ObjectUtils.isEmpty(survey))
            return false;
        //对查询出来的survey的参与人数加1
        survey.setPeoples(survey.getPeoples() + paramsKey.NUM_ONE);
        //根据queryWrapper修改对应survey
        int update = baseMapper.update(survey, queryWrapper);
        return update > paramsKey.NUM_ZERO;
    }

    @Override
    public IPage<surveyVo> getSurveyByCurrent() {
        LambdaQueryWrapper<survey> queryWrapper = new LambdaQueryWrapper<survey>().eq(survey::getCurrently, IS_CURRENTLY.getCode());
        //查询survey表
        survey currentSurvey = baseMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(currentSurvey)) {
            return null;
        }
        String currentRedisKey = redisKey.currentSurveyVoById + currentSurvey.getId();
        //再查询之前判断redis缓存是否存在
        IPage<surveyVo> surveyVoRedis = (IPage<surveyVo>) redisTemplate.opsForValue().get(currentRedisKey);
        if (!ObjectUtils.isEmpty(surveyVoRedis)) {
            return surveyVoRedis;
        }
        //根据查询到的survey获取id,调用上面的方法
        IPage<surveyVo> currentSurveyVO = getSurveyById(currentSurvey.getId());
        //存放进redis作缓存
        redisTemplate.opsForValue().set(currentRedisKey, currentSurveyVO, TimeOut, TimeUnit.HOURS);
        return currentSurveyVO;
    }
}
